home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / gr_col.exe / GR_READ.ME < prev    next >
Text File  |  1993-04-17  |  9KB  |  168 lines

  1.                                 USING WRITELN WHILE IN GRAPHICS
  2.  
  3.  
  4. For some time I have been intrigued with the idea of using standard text
  5. output routines like write, writeln, gotoXY, textcolor, etc. while in 640 X
  6. 480 VGA graphics.  Why would anyone want to do that? Well, for one thing, it's
  7. easier! Horse puckey, you say: what's the matter with Outtext and OuttextXY?
  8. For starters, I have to convert everything to a string. For another, the
  9. functions are not as flexible as writeln, since I can only output one string
  10. at a time. For a third reason, the default system font is ugly and the stroke
  11. fonts use more memory and are slow.
  12.  
  13. Conventional wisdom (i.e., that taught by the "experts") says that you really
  14. can't use write/writeln and read/readln effectively while in graphics. All the
  15. books go to great lengths to develop elaborate routines for doing keyboard
  16. input and graphics text output when plain old readln and writeln work just
  17. fine.
  18.  
  19. But, I hear you say, you can't text control position precisely and you can't
  20. control color well at all when using text I/O. And, you have to remember to
  21. turn DirectVideo off.  As it turns out, these are real limitations, but they
  22. can be gotten around. Almost.  I still use Outtext when I want its power but I
  23. use writeln for ease and speed.
  24.  
  25. The programs I'm about to describe alleviate many of the limitations of
  26. graphics use of text I/O, namely color control and blinking text.
  27.  
  28. First, some background.
  29.  
  30. As is well known (I think), IBM text video architecture controls screen
  31. appearance with "attribute" bytes for each character of text on screen. Of the
  32. 8 bits, the lower 4 bits are for the text foreground color (4 bits = 16
  33. possible colors). The next 3 bits define background color (3 bits = 8 colors),
  34. which is why you ordinarily can't get the high intensity colors (like
  35. LightCyan) for backgrounds. The high order bit is normally used to set
  36. blinking text.
  37.  
  38. However, a BIOS int 10h sub-function 10h can, among other things, change the
  39. way the blink bit is interpreted.  In pure text mode, the blink bit (bit 7 of
  40. the attribute byte) can be used to select blinking and normal text, or it can
  41. be used to select high intensity or normal backgrounds. So, you CAN have the
  42. high intensity backgrounds.  A simple assembly fragment can do this:
  43.  
  44.            PROCEDURE HiBit; assembler;
  45.              asm
  46.                MOV AX, 1003H
  47.                MOV BL, Blink
  48.                INT 10H
  49.              end;
  50.  
  51. If Blink in the above routine is set to "1", bit 7 will select blinking text.
  52. If Blink is set to "0", then high intensity backgrounds can be used.
  53. All that remains is to make sure that bit 7 of the attribute byte is set.  
  54. This can be done one of two ways:
  55.  
  56.   TextAttr := TextAttr or $80
  57.   TextColor( Color + 128 );      { color can be 0 to 15 }
  58. Note that to "clear" bit 7 you can do one of these two things:
  59.  
  60.   TextAttr := TextAttr and $7F
  61.   TextColor( Color );            { color can be 0 to 15 }
  62.  
  63. Now for the fun part: in graphics the BIOS uses bit 7 of the same attribute
  64. byte to control how text is written to the graphics screen! If bit 7 = 0 (the
  65. normal case), text is written with the desired foreground color (TextColor
  66. again) and the default background color, normally black. This is why write-ing
  67. text onto graphics looks dumb: the background of all the characters wipes out
  68. your pretty graphics picture.
  69.  
  70. But, if bit 7 = 1, then the BIOS XOR's the text over the top of the existing
  71. graphic! Wow! think of the possibilities! For one, its now super easy to erase
  72. a line of text. No more tedious overwrites with "background" color or weird
  73. schemes like using Bar or Bar3D to "erase" the text. Now, all you have to do
  74. is re-write the text and voila, it disappears! Or, more correctly, anything
  75. XOR'd onto itself restores the image to what it was before anything was drawn
  76. (this is the theory behind the XORmode of graphics).
  77.  
  78. Ah, but there's a problem (isn't there always?). When you XOR text onto a
  79. graphic, the colors come out all wonky. Again, more correctly, the text color
  80. becomes the inverse of what you thought it'd be because of XOR swapping all
  81. the color bits around.
  82.  
  83. If only you could figure out in advance what the inverse of a given text color
  84. against a given background color is, you could supply that to TextColor and
  85. your text would XOR back to the original "desired" color.
  86.  
  87. Well, now you can! With the help of a utility procedure I hacked together
  88. (XorColConv in the GR_COL2G.PAS and GR_DEMO1.PAS files).
  89.  
  90. Briefly, what the XorColConv procedure does is this: it XORs the bits for
  91. background (graphic) color and foreground (text) color to get an inverse
  92. color. Then, this "color" is compared to the 16 standard VGA colors for a
  93. match.  2/3 of the times you try this, you'll get a match. The rest of the
  94. time, the resulting "color" is a legal VGA value, but not one of the colors in
  95. the standard 16-color palette. 
  96.  
  97. Remembering that the Red/Green/Blue (RGB) values for a VGA color can each have
  98. 64 values (0 to 63), you could have up to 64 * 64 * 64 = 262,144 possible
  99. colors, of which any 16 can be used at a time. You did remember that, didn't
  100. you?  Well, it turns out that out of all possible combinations of "standard"
  101. background and foreground colors, there are only 29 "exception" RGB values.
  102. This can easily be put into a lookup table, which is what I did.
  103.  
  104. I have to confess, though, that this all wasn't obvious to me when I started
  105. out to write XorColConv. By trial and error, I discovered what was going on
  106. and developed a first-cut look-up table. Then by looking at the resulting
  107. colors visually, I adjusted the exception table to have an acceptable color
  108. mapping when the XOR business didn't come out right.
  109.  
  110. To make things easy for myself, I converted the RGB values into a single
  111. longint value so that the XOR business was easier and the look-up table was
  112. simpler to construct.  Essentially, I combined the RGB values into one integer
  113. like this:
  114.  
  115. Using LightBlue as an example, Red = $15, Green = $15, Blue = $3F. This gives
  116. a combined value of $15153F = 1381695 decimal.  Similarly, I calculated the
  117. other 14 colors (black is 0 in any language).
  118. The exception colors were found by printing diagnostics in my procedure.
  119.  
  120. Whew! What good is all this stuff?
  121.  
  122. If you hand XorColConv the background and foreground color you want, it gives
  123. you the XOR color back. Then, you set TextColor + 128 and you're done. All
  124. this is described in excruciating detail in the accompanying demo programs.
  125.  
  126. The first, GR_COL2G.PAS, is a demo of how each of the 16 VGA colors looks when
  127. XOR'd on each of the 16 color backgrounds. It also outputs text files of all
  128. the stuff I've been talking about above. This ain't too useful unless you,
  129. too, are trying to understand all this gibberish.
  130.  
  131. The second program, GR_DEMO1.PAS, is a simple demonstration of how these
  132. techniques can be used. It simply writes some text to the screen, erases it
  133. one character at a time, then re-writes again. Finally, it shows how blinking
  134. text can be simulated in graphics.
  135.  
  136. Whoa! Blinking text? I bet you thought that was impossible or at least a pain
  137. in the butt.  Well, it ain't really blinking text, but it is a good simulation
  138. once you imagine blinking as nothing more than write-erase-write-erase, etc.
  139. for as long as you want it to blink.
  140.  
  141. Finally, there's a simple utility program, RECOL3.PAS which was used to
  142. construct the exception color look-up table from the data provided by
  143. GR_COL2G.PAS.
  144.  
  145. There's also a few Turbo Pascal limitations (at least, I haven't figured out a
  146. work-around yet!).  One is that TP's implementation of write/writeln isn't
  147. standard BIOS stuff. It takes advantage of the fact that a character is
  148. normally 14 pixels high, plus a couple for inter-line spacing. This turns out
  149. to use only 400 of the available 480 pixels on a VGA graphics screen(16 pixels
  150. * 25 lines = 400). So its not quite 80 X 25 VGA text (normal 25 lines would be
  151. 480 / 25 = 19.2 pixels high ).  Second, changing text styles (40 characters or
  152. 50 lines) just don't work.
  153.  
  154. Anyway, I hope you